package com.zhou.org.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhou.framework.util.SettingUtil;
import com.zhou.org.common.*;
import com.zhou.util.ListUtil;
import com.zhou.util.NumberUtil;
import com.zhou.util.ObjectUtil;
import com.zhou.util.StringTool;
import com.zhou.org.dao.Right;
import com.zhou.org.dao.SysMenu;
import com.zhou.org.dto.MenuQueryDto;
import com.zhou.org.mapper.SysMenuMapper;
import com.zhou.org.model.TreeSelect;
import com.zhou.org.service.ISysMenuService;
import com.zhou.org.service.OrgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 菜单 业务层处理
 *
 * @author ruoyi
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper,SysMenu> implements ISysMenuService {

    @Autowired
    private OrgService orgService;

    @Override
    public List<SysMenu> selectMenuTreeByUserId(Integer orgId) {
        int org = SettingUtil.getAdminOrgId();
        List<Integer> ids = null;
        if(org > 0){
            ids = orgService.getChildDistinctUserOrgId(org);
        }
        List<SysMenu> menus = selectList(new MenuQueryDto());
        if (ids != null && !ids.contains(orgId)) {
            List<Right> rights = RightUtil.getRight(RightKeyEnum.MENU,"YES",orgId);
            List<Long> idList = new ArrayList<>(rights.size()/2);
            for(Right right : rights){
                if (right.getReject() == 0){
                    idList.add(NumberUtil.safeToLong(right.getObjectKey(),0L));
                }

            }
            menus.removeIf(o-> !idList.contains(o.getMenuId()));
        }
        return menus;
    }

    @Override
    public List<SysMenu> selectMenuTree() {
        List<SysMenu> menus = selectList(new MenuQueryDto());
        return MenuUtil.getChildPerms(menus, 0);
    }

    @Override
    public List<SysMenu> selectList(MenuQueryDto dto) {
        LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
        if(ObjectUtil.isNotEmpty(dto.getParentId())){
            w.eq(SysMenu::getParentId,dto.getParentId());
        }
        if(StringTool.isNotBlank(dto.getMenuType())){
            w.eq(SysMenu::getMenuType,dto.getMenuType());
        }
        if(StringTool.isNotBlank(dto.getMenuName())){
            w.like(SysMenu::getMenuName,StringTool.concat("%",dto.getMenuName(),"%"));
        }
        w.orderByAsc(SysMenu::getOrderNum);
        return list(w);
    }





    /**
     * 构建前端所需要下拉树结构
     *
     * @param menus 菜单列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus)
    {
        List<SysMenu> menuTrees = MenuUtil.buildMenuTree(menus);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    @Override
    public List<SysMenu> getChildByMenuId(Long menuId) {
        LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
        w.eq(SysMenu::getParentId,menuId);
        w.orderByAsc(SysMenu::getOrderNum);
        return list(w);
    }

    /**
     * 是否存在菜单子节点
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public boolean hasChildByMenuId(Long menuId) {
        LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
        w.eq(SysMenu::getParentId,menuId);
        return count(w) > 0;
    }



    /**
     * 校验菜单名称是否唯一
     *
     * @param menu 菜单信息
     * @return 结果
     */
    @Override
    public boolean checkMenuNameUnique(SysMenu menu) {
        long menuId = NumberUtil.safeToLong(menu.getMenuId(), -1L);
        LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
        w.eq(SysMenu::getParentId,menu.getParentId());
        w.eq(SysMenu::getMenuName,menu.getMenuName());
        w.eq(SysMenu::getMenuType,menu.getMenuType());

        SysMenu info = ListUtil.getFirst(list(w));
        return info != null && !Objects.equals(info.getMenuId(),menuId);
    }

    @Override
    public boolean checkMenuCntByPerVal(SysMenu menu){
        if(EnumConstant.TYPE_BUTTON.equals(menu.getMenuType())){
            LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
            w.eq(SysMenu::getPerVal,menu.getPerVal());
            SysMenu info = baseMapper.selectOne(w);
            return info != null && !Objects.equals(info.getMenuId(),menu.getMenuId());
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMenu(SysMenu menu) {
        MenuUtil.formatMenu(menu);
        long menuId = NumberUtil.safeToLong(menu.getMenuId(),0L);
        menu.setUpdateDt(new Date());

        if(menuId > 0L){
            LambdaUpdateWrapper<SysMenu> w = new LambdaUpdateWrapper<>();
            w.eq(SysMenu::getMenuId,menu.getMenuId());
            w.set(SysMenu::getMenuName,menu.getMenuName());
            w.set(SysMenu::getParentId,menu.getParentId());
            w.set(SysMenu::getPath,menu.getPath());
            w.set(SysMenu::getMenuType,menu.getMenuType());
            w.set(SysMenu::getComponent,menu.getComponent());
            w.set(SysMenu::getAffix,menu.getAffix());
            w.set(SysMenu::getIcon,menu.getIcon());
            w.set(SysMenu::getIsFrame,menu.getIsFrame());
            w.set(SysMenu::getQuery,menu.getQuery());
            w.set(SysMenu::getPerVal,menu.getPerVal());
            w.set(SysMenu::getIsCache,menu.getIsCache());
            w.set(SysMenu::getOrderNum,menu.getOrderNum());
            w.set(SysMenu::getVisible,menu.getVisible());
            w.set(SysMenu::getUpdateDt,menu.getUpdateDt());
            update(w);
        }else{
            menu.setCreateDt(menu.getUpdateDt());
            save(menu);
        }
        MenuCache.reloadMenu();
    }

    @Override
    public int getChildMenuCnt(Long menuId) {
        LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
        w.eq(SysMenu::getParentId,menuId);
        return count(w);
    }

    @Override
    public List<SysMenu> getChildMenu(Long menuId) {
        LambdaQueryWrapper<SysMenu> w = new LambdaQueryWrapper<>();
        w.eq(SysMenu::getParentId,menuId);
        w.orderByAsc(SysMenu::getOrderNum);
        return list(w);
    }

    @Override
    public void deleteMenu(Long menuId) {
        removeById(menuId);
        MenuCache.reloadMenu();
    }



}
